﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;


namespace PersianCalendarControl
{
    public enum CalendarViewState
    {
        MonthView = 1,
        YearView = 2,
        DecadeView = 3
    }

    public class CalendarEventArgs:RoutedEventArgs
    {
        private DateTime selectedDateTime;
        public CalendarEventArgs():base() 
        {
            
        }

        public CalendarEventArgs(DateTime dateTime)
            : base()
        {
            SelectedDateTime = dateTime;
        }

        public DateTime SelectedDateTime
        {
            get { return selectedDateTime; }
            set { selectedDateTime = value; }
        }
    }


	public partial class ComposedCalendarViewControl : UserControl
	{
        public delegate void CalendarItemClickedEvent(object sender, CalendarEventArgs e);

        public event CalendarItemClickedEvent OnCalendarItemClicked;




	    private DateTime _currentDate = DateTime.Now;
        public DateTime CurrentDate
        {
            get { return _currentDate; }
            set
            {
                _currentDate = value;
                ChangeView();
            }
        }
	    private PersianCalendar calendar;

        private CalendarViewState currentView = CalendarViewState.MonthView;
        public CalendarViewState CurrentView
        {
            get { return currentView; }
            set
            {
                currentView = value;
                ChangeView();
            }
        }

	   

	    public ComposedCalendarViewControl()
		{
			// Required to initialize variables
			InitializeComponent();
	        calendar = new PersianCalendar(); 
            this.headerLabel.OnHeaderLabelClicked += new HeaderLabel.HeaderLabelClickedEvent(headerLabel_OnHeaderLabelClicked);
            foreach (FrameworkElement element in this.MonthViewGrid.Children)
            {
                if (element is CalendarItemLabelButton)
                {
                    CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton) element;
                    calendarItemLabelButton.OnCalendarItemClicked +=
                        new CalendarItemLabelButton.CalendarItemClickedEvent(
                            CalendarItemLabelButton_OnCalendarItemClicked);
                }
            }
            foreach (FrameworkElement element in this.YearViewGrid.Children)
            {
                CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton)element;
                calendarItemLabelButton.OnCalendarItemClicked += new CalendarItemLabelButton.CalendarItemClickedEvent(CalendarItemLabelButton_OnCalendarItemClicked);
            }
            foreach (FrameworkElement element in this.DecadeViewGrid.Children)
            {
                CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton)element;
                calendarItemLabelButton.OnCalendarItemClicked += new CalendarItemLabelButton.CalendarItemClickedEvent(CalendarItemLabelButton_OnCalendarItemClicked);
            }
            

            this.btnPrev.OnNavigationButtonClicked += new NavigationButton.NavigationButtonClickedEvent(navigationButton_PrevButtonClicked);
            this.btnNext.OnNavigationButtonClicked += new NavigationButton.NavigationButtonClickedEvent(navigationButton_NextButtonClicked);
		    
             ChangeView();
	       
		}


        void navigationButton_NextButtonClicked(object sender, RoutedEventArgs e)
        {
            if (currentView == CalendarViewState.MonthView)
            {
                int m = calendar.GetMonth(this.CurrentDate);
                this.CurrentDate = calendar.AddMonths(this.CurrentDate, 1);
                
                
            }
            else if (currentView == CalendarViewState.YearView)
            {
                this.CurrentDate = calendar.AddYears(this.CurrentDate,1);
                

            }
            else if (currentView == CalendarViewState.DecadeView)
            {
                this.CurrentDate = calendar.AddYears(this.CurrentDate, 12);
            }



            
          
            
            this.headerLabel.CurrentView = this.currentView;
            this.headerLabel.CurrentDate = this.CurrentDate;
            
            
        }

        void navigationButton_PrevButtonClicked(object sender, RoutedEventArgs e)
        {
            if (currentView == CalendarViewState.MonthView)
            {
                int m = calendar.GetMonth(this.CurrentDate);
                this.CurrentDate = calendar.AddMonths(this.CurrentDate, -1);


            }
            else if (currentView == CalendarViewState.YearView)
            {
                this.CurrentDate = calendar.AddYears(this.CurrentDate, -1);


            }
            else if (currentView == CalendarViewState.DecadeView)
            {
                this.CurrentDate = calendar.AddYears(this.CurrentDate, -12);
            }




            ChangeView();

            this.headerLabel.CurrentView = this.currentView;
            this.headerLabel.CurrentDate = this.CurrentDate;
            
        }
        

        void CalendarItemLabelButton_OnCalendarItemClicked(object sender, RoutedEventArgs e)
        {
            CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton)sender;
            PersianCalendar persianCalendar = new PersianCalendar();
            if(CurrentView == CalendarViewState.MonthView)
            {
                if (OnCalendarItemClicked != null)  OnCalendarItemClicked(calendarItemLabelButton,new CalendarEventArgs(calendarItemLabelButton.CurrentDate));

                int newDay = persianCalendar.GetDayOfMonth(calendarItemLabelButton.CurrentDate);
                int newMonth = persianCalendar.GetMonth(calendarItemLabelButton.CurrentDate);
                int newYear = persianCalendar.GetYear(calendarItemLabelButton.CurrentDate);

                int oldDay = persianCalendar.GetDayOfMonth(this.CurrentDate);
                int oldMonth = persianCalendar.GetMonth(this.CurrentDate);
                int oldYear = persianCalendar.GetYear(this.CurrentDate);



                this.CurrentDate = persianCalendar.ToDateTime(oldYear, oldMonth, newDay, 0, 0, 0, 0);

                CurrentView = CalendarViewState.MonthView;
            }

            else if (CurrentView == CalendarViewState.YearView)
            {

                int newDay = persianCalendar.GetDayOfMonth(calendarItemLabelButton.CurrentDate);
                int newMonth = persianCalendar.GetMonth(calendarItemLabelButton.CurrentDate);
                int newYear = persianCalendar.GetYear(calendarItemLabelButton.CurrentDate);

                int oldDay = persianCalendar.GetDayOfMonth(this.CurrentDate);
                int oldMonth = persianCalendar.GetMonth(this.CurrentDate);
                int oldYear = persianCalendar.GetYear(this.CurrentDate);



                this.CurrentDate = persianCalendar.ToDateTime(oldYear, newMonth, oldDay, 0, 0, 0, 0);


                //this.CurrentDate = calendarItemLabelButton.CurrentDate;
                CurrentView = CalendarViewState.MonthView;
                this.headerLabel.CurrentView = this.currentView;
                this.headerLabel.CurrentDate = this.CurrentDate;
                this.headerLabel.IsEnabled = true;
               
               
            }
            else if (CurrentView == CalendarViewState.DecadeView)
            {
                int newDay = persianCalendar.GetDayOfMonth(calendarItemLabelButton.CurrentDate);
                int newMonth = persianCalendar.GetMonth(calendarItemLabelButton.CurrentDate);
                int newYear = persianCalendar.GetYear(calendarItemLabelButton.CurrentDate);

                int oldDay = persianCalendar.GetDayOfMonth(this.CurrentDate);
                int oldMonth = persianCalendar.GetMonth(this.CurrentDate);
                int oldYear = persianCalendar.GetYear(this.CurrentDate);


                this.CurrentDate = persianCalendar.ToDateTime(newYear, oldMonth, oldDay, 0, 0, 0, 0);


                //this.CurrentDate = calendarItemLabelButton.CurrentDate;
                CurrentView = CalendarViewState.YearView;
                this.headerLabel.CurrentView = this.currentView;
                this.headerLabel.CurrentDate = this.CurrentDate;
                this.headerLabel.IsEnabled = true;
            }
            

        }
        

        void headerLabel_OnHeaderLabelClicked(object sender, RoutedEventArgs e)
        {
            if (CurrentView == CalendarViewState.MonthView)
            {
                CurrentView = CalendarViewState.YearView;
                this.headerLabel.CurrentView = this.currentView;
                this.headerLabel.CurrentDate = this.CurrentDate;
                this.headerLabel.IsEnabled = true;
                
                
            }
            else if (CurrentView == CalendarViewState.YearView)
            {
                CurrentView = CalendarViewState.DecadeView;
                this.headerLabel.CurrentView = this.currentView;
                this.headerLabel.CurrentDate = this.CurrentDate; 
                this.headerLabel.IsEnabled = true;
               
            }
            else if (CurrentView == CalendarViewState.DecadeView)
            {
                this.headerLabel.CurrentView = this.currentView;
                this.headerLabel.CurrentDate = this.CurrentDate; 
                this.headerLabel.IsEnabled = false;
               
            }
        }

        private void ChangeView()
        {
            if (currentView == CalendarViewState.MonthView)
            {
                FillDays();              
   	   		  	this.MonthViewGrid.Visibility = System.Windows.Visibility.Visible;
                this.YearViewGrid.Visibility = System.Windows.Visibility.Collapsed;
                this.DecadeViewGrid.Visibility = System.Windows.Visibility.Collapsed;
            }
            else if (currentView == CalendarViewState.YearView)
            {
                FillYear();				
                this.MonthViewGrid.Visibility = System.Windows.Visibility.Collapsed;
                this.YearViewGrid.Visibility = System.Windows.Visibility.Visible;
                this.DecadeViewGrid.Visibility = System.Windows.Visibility.Collapsed;
            }
            else if (currentView == CalendarViewState.DecadeView)
            {
                FillDecade();
				//VisualStateManager.GoToState(this, "DecadeViewState", false);
                this.MonthViewGrid.Visibility = System.Windows.Visibility.Collapsed;
                this.YearViewGrid.Visibility = System.Windows.Visibility.Collapsed;
                this.DecadeViewGrid.Visibility = System.Windows.Visibility.Visible;
            }
        }

	    

	    private void FillDays()
        {
            foreach(FrameworkElement element in this.MonthViewGrid.Children)
            {
                if (element is CalendarItemLabelButton)
                {
                    CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton) element;
                    calendarItemLabelButton.CellIndex = Grid.GetColumn(element) + 7*Grid.GetRow(element);
                    calendarItemLabelButton.CurrentDate = this.CurrentDate;
                }
            }
            this.headerLabel.CurrentDate = this.CurrentDate; 
        }


        private void FillYear()
        {
            foreach (FrameworkElement element in this.YearViewGrid.Children)
            {
                CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton)element;
                calendarItemLabelButton.CellIndex = Grid.GetColumn(element) + 4 * Grid.GetRow(element);
                calendarItemLabelButton.CurrentDate = this.CurrentDate;
                
            }
            this.headerLabel.CurrentDate = this.CurrentDate;
        }

        private void FillDecade()
        {
            foreach (FrameworkElement element in this.DecadeViewGrid.Children)
            {
                CalendarItemLabelButton calendarItemLabelButton = (CalendarItemLabelButton)element;
                calendarItemLabelButton.CellIndex = Grid.GetColumn(element) + 4 * Grid.GetRow(element);
                calendarItemLabelButton.CurrentDate = this.CurrentDate;
                
            }
            this.headerLabel.CurrentDate = this.CurrentDate;
        }
	}
}